package com.task.core.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;

import com.github.pagehelper.PageHelper;
import com.task.common.annotation.DataScope;
import com.task.common.constant.ErrorCodeConstants;
import com.task.common.core.redis.RedisCache;
import com.task.common.enums.QuestionOperationTypeEnum;
import com.task.common.enums.QuestionPromptContentEnum;
import com.task.common.exception.ServiceException;
import com.task.common.info.*;
import com.task.common.redis.RedisKeyConstants;
import com.task.common.utils.uuid.UUID;
import com.task.core.domain.EngineSchemeInfo;
import com.task.core.domain.MissionInfo;
import com.task.core.dto.request.*;
import com.task.core.mapper.*;
import com.task.core.vo.resp.QuestionShowRespVo;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.task.common.enums.QuestionInfoTypeEnum;
import com.task.common.utils.SecurityUtils;
import com.task.core.service.EngineSchemeService;
import com.task.core.service.EngineService;
import com.task.core.service.QuestionInfoService;
import org.springframework.util.ObjectUtils;

import static com.github.pagehelper.page.PageMethod.startPage;

/**
 * @author 迪迦.
 * @date 2025/2/11 10:26
 */
@Service
public class QuestionInfoServiceImpl implements QuestionInfoService {

  @Resource
  private QuestionInfoMapper questionInfoMapper;

  @Resource
  private EngineService engineService;

  @Resource
  private EngineSchemeService engineSchemeService;

  @Resource
  private RedisCache redisCache;

  @Resource
  private MissionMapper missionMapper;

  @Resource
  private PluginMapper pluginMapper;

  @Resource
  private IpFraudMapper ipFraudMapper;

  @Resource
  private DeviceFraudMapper deviceFraudMapper;

  @Resource
  private EngineSchemeMapper engineSchemeMapper;

  @Resource
  private ProxyMapper proxyMapper;


  @Override
  public List<String> getDataCodes(QuestionInfoTypeEnum questionType, String operationCode) {
    if (QuestionInfoTypeEnum.ENGINE.name().equals(questionType.name())) {
      //引擎是是直接返回所有引擎方案code
      return engineSchemeService.getAllCodesByEngineCode(operationCode);
    }
    return questionInfoMapper.getDataCodes(questionType.getTableName(), questionType.getColumnName(), operationCode);
  }

  @Override
  public void insertQuestion(QuestionInfoRequestDTO request) {
    List<String> dataCodes = getDataCodes(request.getQuestionType(), request.getOperationCode());
    if (CollectionUtils.isEmpty(dataCodes)) {
      return;
    }
    List<QuestionPageInfo> questionInfos = new ArrayList<>();
    for (String dataCode : dataCodes) {
      questionInfos.add(new QuestionPageInfo(request.getQuestionType().name(), dataCode, request.getShowContent(), request.getPromptCode(),request.getOperationType(),request.getNow()));
    }
    questionInfoMapper.insertQuestion(questionInfos, SecurityUtils.getUserId());
  }

  @Override
  public void fixQuestion(QuestionInfoRequestDTO request) {
    questionInfoMapper.fixQuestion(request.getQuestionType().name(), request.getDataCode(), new Date(), request.getOperationBy());
  }

  @Override
  public boolean checkVersionCode(QuestionInfoTypeEnum type, String nextCode, String versionCode) {
    return questionInfoMapper.checkVersionCode(type.getOtherTableName(), nextCode, versionCode) == 0;
  }

  @Override
  public List<QuestionShowInfo> getQuestionInfosByTypeAndCode(String type, String dataCode) {
    return questionInfoMapper.getQuestionInfosByTypeAndCode(type, dataCode);
  }

  @Override
  public List<QuestionShowInfo> getQuestionInfosByTypeAndCodes(String type, List<String> dataCode) {
    return questionInfoMapper.getQuestionInfosByTypeAndCodes(type, dataCode);
  }

  @Override
  public void insertQuestionByTypeIsMission(String code) {
    QuestionShowInfo questionShowInfo = new QuestionShowInfo();
    questionShowInfo.setQuestionType(QuestionInfoTypeEnum.MISSION.name());
    questionShowInfo.setCode(UUID.randomUUID().toString().replace("-",""));
    questionShowInfo.setDataCode(code);
    questionInfoMapper.insertQuestionByTypeIsMission(questionShowInfo);
  }

  @Override
  public QuestionShowInfo getQuestionInfosByMissionTypeAndCode(String type, String missionCode) {
    return questionInfoMapper.getQuestionInfosByMissionTypeAndCode(type,missionCode);
  }

  @Override
  public void updatetQuestionByTypeIsMission(String code) {
    questionInfoMapper.updatetQuestionByTypeIsMission(code);
  }

  @Override
  @DataScope(deptAlias = "dept", userAlias = "su")
  public List<QuestionShowRespVo> getQuestionByPage(QuestionRequestDTO request) {
    //先查询当前查看用户是不是管理员,如果不是就需要先查询属于哪个部门,部门下面能看到哪些数据
    List<String> dataCodes = questionInfoMapper.getCanSeeCodes(request);
    if (CollectionUtils.isEmpty(dataCodes)) {
      return Collections.emptyList();
    }
    request.setDataCodes(dataCodes);
    startPage(request.getPageNum(), request.getPageSize());
    List<QuestionShowRespVo> questions = questionInfoMapper.getQuestionByPage(request);

    for (QuestionShowRespVo question : questions) {
      getQuesionPrompt(question);
    }
    return questions;
  }

  private void getQuesionPrompt(QuestionShowRespVo question) {
    switch (QuestionInfoTypeEnum.getEnumByName(question.getQuestionType())){
      case MISSION:
        MissionInfo missionByCode = missionMapper.getMissionByCode(question.getDataCode());
        if(ObjectUtils.isEmpty(missionByCode)){
          break;
        }
        question.setShowContent(missionByCode.getMissionName()+","+ErrorCodeConstants.AVAILABLE_DATA_SOURCE_IS_USED.getMsg());
      case PLUGIN:
        PluginRequestDTO pluginRequestDTO = new PluginRequestDTO();
        pluginRequestDTO.setCode(question.getDataCode());
        PluginInfo pluginByCode = pluginMapper.getPluginByCode(pluginRequestDTO);
        if(ObjectUtils.isEmpty(pluginByCode)){
          break;
        }
        if(QuestionOperationTypeEnum.DELETE.getCode().equals(question.getOperationType())){
          question.setShowContent(pluginByCode.getPluginName()+","+QuestionPromptContentEnum.PLUGIN_DELETE_PROMPT_CONTENT.getMsg());
        }else {
          question.setShowContent(pluginByCode.getPluginName()+","+question.getShowContent());
        }
        break;
      case IP_FRAUD:
        IpFraudRequestDTO ipFraudRequestDTO = new IpFraudRequestDTO();
        ipFraudRequestDTO.setCode(question.getDataCode());
        IpFraudInfo ipFraudByCode = ipFraudMapper.getIpFraudByCode(ipFraudRequestDTO);
        if(ObjectUtils.isEmpty(ipFraudByCode)){
          break;
        }
        if(QuestionOperationTypeEnum.DELETE.getCode().equals(question.getOperationType())){
          question.setShowContent(ipFraudByCode.getIpFraudName()+","+QuestionPromptContentEnum.IP_FRAUD_DELETE_PROMPT_CONTENT.getMsg());
        }else {
          question.setShowContent(ipFraudByCode.getIpFraudName()+","+question.getShowContent());
        }
        break;
      case DEVICE_FRAUD:
        DeviceFraudRequestDTO deviceFraudRequestDTO = new DeviceFraudRequestDTO();
        deviceFraudRequestDTO.setCode(question.getDataCode());
        DeviceFraudInfo deviceFraudByCode = deviceFraudMapper.getDeviceFraudByCode(deviceFraudRequestDTO);
        if(ObjectUtils.isEmpty(deviceFraudByCode)){
          break;
        }
        if(QuestionOperationTypeEnum.DELETE.getCode().equals(question.getOperationType())){
          question.setShowContent(deviceFraudByCode.getDeviceFraudName()+","+QuestionPromptContentEnum.DEVICE_FRAUD_DELETE_PROMPT_CONTENT.getMsg());
        }else {
          question.setShowContent(deviceFraudByCode.getDeviceFraudName()+","+question.getShowContent());
        }
        break;
      case PROXY:
        ProxyRequestDTO proxyRequestDTO = new ProxyRequestDTO();
        proxyRequestDTO.setCode(question.getDataCode());
        ProxyInfo proxyByCode = proxyMapper.getProxyByCode(proxyRequestDTO);
        if(ObjectUtils.isEmpty(proxyByCode)){
          break;
        }
        if(QuestionOperationTypeEnum.DELETE.getCode().equals(question.getOperationType())){
          question.setShowContent(proxyByCode.getProxyName()+","+QuestionPromptContentEnum.PROXY_DELETE_PROMPT_CONTENT.getMsg());
        }else {
          question.setShowContent(proxyByCode.getProxyName()+","+question.getShowContent());
        }
        break;
      case ENGINE:
        EngineSchemeInfo engineSchemeByCode = engineSchemeMapper.getEngineSchemeByCode(question.getDataCode());
        if(ObjectUtils.isEmpty(engineSchemeByCode)){
          break;
        }
        if(QuestionOperationTypeEnum.DELETE.getCode().equals(question.getOperationType())){
          question.setShowContent(engineSchemeByCode.getEngineSchemeName()+","+QuestionPromptContentEnum.ENGINE_DELETE_PROMPT_CONTENT.getMsg());
        }else {
          question.setShowContent(engineSchemeByCode.getEngineSchemeName()+","+question.getShowContent());
        }
        break;
    }
  }

  @Override
  public void deleteQuestion(String questionCode) {
    QuestionShowRespVo questionByCode =  questionInfoMapper.getQuestionByCode(questionCode);
    if(!ObjectUtils.isEmpty(questionByCode)){
      throw new ServiceException(ErrorCodeConstants.UNFIXED_ISSUES_NOT_DELETED.getMsg());
    }
    questionInfoMapper.deleteQuestion(questionCode);
  }

  @Override
  public void chackFixQuestion(String questionCode) {
    QuestionShowRespVo question = questionInfoMapper.getQuestionByCode(questionCode);
    if (ObjectUtils.isEmpty(question)) {
      throw new ServiceException(ErrorCodeConstants.QUESTION_NOT_EXIST.getMsg());
    }
    String key = RedisKeyConstants.QUESTION_FIX_INFO.formatKey(question.getDataCode(), question.getCode());
    if (redisCache.hasKey(key)) {
      questionInfoMapper.fixQuestionByCode(question.getCode(),question.getQuestionType(), question.getDataCode(), new Date(), SecurityUtils.getUserId());
      redisCache.deleteObject(key);
    } else {
      throw new ServiceException(ErrorCodeConstants.QUESTION_FIX_INFO_NOT_EXIST.getMsg());
    }
  }

}
